﻿using AutoMapper;
using Modules;
using Modules.Attachment;
using Modules.Common;
using Modules.Project;
using PmSoft;
using Modules.System.User;
using PmSoft.ApplicationContext;
using Pipelines.Sockets.Unofficial.Arenas;
using PmSoft.Entity;

namespace ManagementApi.Models.Project;

/// <summary>
/// 保证金缴纳信息Dto
/// </summary>
public class ProjectGuaranteePaymentDto : OperateDto
{
    /// <summary>
    ///
    ///</summary>
    public int Id { get; set; }

    /// <summary>
    /// 关联项目Id
    ///</summary>
    public int ProjectId { get; set; }

    /// <summary>
    /// 关联保证金账户Id
    ///</summary>
    public int? GuaranteeAccountId { get; set; }

    /// <summary>
    /// 缴纳主体名称
    /// </summary>
    public string? PaymentName { get; set; }

    /// <summary>
    /// 缴纳主体社会统一信用代码
    /// </summary>
    public string? PaymentCode { get; set; }

    /// <summary>
    /// 缴存类型（100：按预设比例缴存 101：免除保证金 102：减少保证金应交金额 103：缓缴保证金 104：增加保证金应缴金额）
    ///</summary>
    public 缴存类型? DepositeType { get; set; }

    /// <summary>
    /// 缴存类型
    /// </summary>
    public string? DepositeTypeName { get; set; }

    /// <summary>
    /// 应缴纳金额
    ///</summary>
    public decimal? Payable { get; set; }

    /// <summary>
    /// 已缴纳金额/担保金额/保单金额
    ///</summary>
    public decimal? Paid { get; set; }

    /// <summary>
    /// 差异化缴存金额（应缴纳金额和已缴纳金额的差值，取正值）
    ///</summary>
    public decimal? Difference { get; set; }

    /// <summary>
    /// 缴存起始日期/有效期起始起始日期
    ///</summary>
    public DateTime? StartDate { get; set; }

    /// <summary>
    /// 有效期终止日期
    ///</summary>
    public DateTime? EndDate { get; set; }

    /// <summary>
    /// 工程担保保函函号/保险单号
    ///</summary>
    public string? GuaranteeLetterNo { get; set; }

    /// <summary>
    /// 保证金状态（0：待核实 1：有效 2：失效 -1：审核不通过）
    ///</summary>
    public 保证金状态 Status { get; set; }

    /// <summary>
    /// 审核意见
    /// </summary>
    public string? CheckReason { get; set; }

    /// <summary>
    /// 保证金状态
    /// </summary>
    public string? StatusName { get; set; }

    /// <summary>
    /// 是否退还（0：否 1：是）
    ///</summary>
    public bool HasReturn { get; set; }

    /// <summary>
    /// 创建人
    ///</summary>
    public string? Creator { get; set; }

    /// <summary>
    /// 创建时间
    ///</summary>
    public DateTime? CreateTime { get; set; }

    /************* 额外显示字段 ****************/

    /// <summary>
    /// 项目名称
    /// </summary>
    public string? ProjectName { get; set; }

    /// <summary>
    /// 项目编号
    /// </summary>
    public string? ProjectNum { get; set; }

    /// <summary>
    /// 项目地址
    /// </summary>
    public string? FullAddress { get; set; }

    /// <summary>
    /// 保证金账号名称
    /// </summary>
    public string? GuaranteeAccountName { get; set; }

    /// <summary>
    /// 归属人社
    /// </summary>
    public string? RsName { get; set; }

    /// <summary>
    /// 开户银行名称
    /// </summary>
    public string? BankName { get; set; }

    /// <summary>
    /// 开户银行账户
    /// </summary>
    public string? BankNo { get; set; }

    /// <summary>
    /// 保证金编号
    /// </summary>
    public string? GuaranteeAccountCode { get; set; }

    /// <summary>
    /// 保证金方式
    /// </summary>
    public 保证金类型? GuaranteeAccountType { get; set; }

    /// <summary>
    /// 保证金方式
    /// </summary>
    public string? GuaranteeAccountTypeName { get; set; }

    /// <summary>
    /// 工程担保公司负责人/保险公司负责人
    ///</summary>
    public string? Superintendent { get; set; }

    /// <summary>
    /// 工程担保公司负责人联系电话/保险公司负责人电话
    ///</summary>
    public string? SuperintendentMobile { get; set; }

    /// <summary>
    /// 工程担保公司信用代码
    /// </summary>
    public string? Socialcreditcode { get; set; }

    /// <summary>
    /// 退还信息
    /// </summary>
    public ProjectGuaranteeRefund? ProjectGuaranteeRefund { get; set; }

    /// <summary>
    /// 保函凭证
    /// </summary>
    public IEnumerable<AttachmentsForm<int>>? Attachments { get; set; }
}

/// <summary>
/// 保证金缴纳信息扩展
/// </summary>
public static class ProjectGuaranteePaymentExceptions
{
    /// <summary>
    /// 返回前端显示数据
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    public static ProjectGuaranteePaymentDto AsDto(this ProjectGuaranteePayment entity, IApplicationContext applicationContext)
    {
        ProjectGuaranteePaymentDto projectGuaranteePaymentDto = new();
        var dto = applicationContext.GetService<IMapper>().Map(entity, projectGuaranteePaymentDto);
        var projectService = applicationContext.GetService<ProjectService>();
        var areaService = applicationContext.GetService<Modules.System.Area.AreaService>();
        var projectGuaranteeAccountService = applicationContext.GetService<ProjectGuaranteeAccountService>();
        var projectGuaranteeRefundService = applicationContext.GetService<ProjectGuaranteeRefundService>();
        var projectAttachmentService = applicationContext.GetService<ProjectAttachmentService>();

        dto.DepositeTypeName = dto.DepositeType?.GetDescription();
        dto.StatusName = dto.Status.GetDescription();

        #region 项目信息

        var project = projectService.GetProjectInfo(entity.ProjectId);
        if (project != null)
        {
            dto.ProjectName = project.Name;
            dto.ProjectNum = project.PrjNum;
            var area = areaService.GetAreaTuple(project.AreaCode);
            dto.FullAddress = areaService.GetAreaFullName(area.ProvinceCode, area.CityCode, area.AreaCode) + project.Address;

            #region 主管单位数据权限

            if (applicationContext.CurrentUser is IDeptUser deptUser)
            {
                if (deptUser.IsSuperAdministrator())
                    dto.HasEdit = true;
                else if (deptUser.IsRSAdministrator())
                {
                    if (deptUser.Level == AdministrativeLevel.City && project.CityCode == deptUser.CityCode)
                        dto.HasEdit = true;
                    if (deptUser.Level == AdministrativeLevel.Area && project.AreaCode == deptUser.AreaCode)
                        dto.HasEdit = true;
                    if (deptUser.Level == AdministrativeLevel.Province)
                        dto.HasEdit = true;
                }
                else dto.HasEdit = false;
            }

            #endregion 主管单位数据权限
        }

        #endregion 项目信息

        #region 保证金账户信息

        var projectGuaranteeAccount = projectGuaranteeAccountService.GetProjectGuaranteeAccount(entity.GuaranteeAccountId);
        dto.GuaranteeAccountName = projectGuaranteeAccount?.Name ?? string.Empty;
        dto.GuaranteeAccountCode = projectGuaranteeAccount?.Code ?? string.Empty;
        dto.GuaranteeAccountTypeName = projectGuaranteeAccount?.Type.GetDescription() ?? string.Empty;
        dto.BankName = projectGuaranteeAccount?.BankName;
        dto.BankNo = projectGuaranteeAccount?.BankNo.ToString();
        dto.RsName = projectGuaranteeAccount?.RsName;
        dto.GuaranteeAccountType = projectGuaranteeAccount?.Type;
        dto.Superintendent = projectGuaranteeAccount?.Superintendent;
        dto.SuperintendentMobile = projectGuaranteeAccount?.SuperintendentMobile;
        dto.Socialcreditcode = projectGuaranteeAccount?.Socialcreditcode;

        #endregion 保证金账户信息

        #region 保证金退还信息

        dto.ProjectGuaranteeRefund = projectGuaranteeRefundService.GetProjectGuaranteeRefundByGuaranteePaymentId(entity.Id);

        #endregion 保证金退还信息

        #region 保证金附件信息

        var attachments = projectAttachmentService.GetSysAttachmentByObjectIdAndType(dto.Id, 附件类型.保证金保函凭证, 项目附件租户.ProjectGuaranteePayment);
        List<AttachmentsForm<int>> attach = new();
        foreach (var item in attachments)
        {
            AttachmentsForm<int> attachmentsForm = new()
            {
                AttachmentId = item.Id,
                AttachmentName = item.FriendlyName,
            };
            attach.Add(attachmentsForm);
        }
        dto.Attachments = attach;

        #endregion 保证金附件信息

        return dto;
    }
}